/* eslint-disable @iceworks/best-practices/recommend-polyfill */
import carImg from '@/assets/car02.png';
import { useStore } from '@/hooks';
import { t } from '@lingui/macro';
import { observer } from 'mobx-react-lite';
import React, { useEffect, useRef, useState } from 'react';
import { Label, Marker } from 'react-bmapgl';
import { fillLocations } from '../stores/TaskMapStore';
import _ from 'lodash';

const { BMapGL } = global;

function VehicleMap() {
  const { taskMapStore: store } = useStore();
  const { mapRef } = store.mapContext;
  const newLocs = useRef({}).current; // map of GeoLocation
  const [data, setData] = useState([]);

  useEffect(() => {
    store.fetchPoints();

    let sub;
    (async () => {
      sub = await store.subscribeLocation({
        filter: {},
        onNext: (loc) => { newLocs[loc.targetId] = loc; },
      });
    })();
    const aniHandle = setInterval(() => processNowLocation(), 2000); // 每2秒处理一次更新
    return () => {
      // console.log('!!!!unsubscrib points');
      clearInterval(aniHandle);
      sub?.cancel();
    };
  }, []);

  useEffect(() => {
    const locations = store.getLocations();
    if (!locations.length) return;

    const _locs = fillLocations(locations);
    locations.length > 1 && mapRef.setViewport((_locs.map((p) => new BMapGL.Point(p.coord.lng, p.coord.lat))));
    locations.length === 1 && mapRef.panTo(_locs[0].coord);
    setData(_locs);
  }, [store.pointKind, store.pointKeyword, store._points]);

  useEffect(() => {
    const coord = store.selectedPoint?.coord;
    if (!coord) return;
    mapRef.panTo(coord, 18);
  }, [store.selectedPoint]);

  async function processNowLocation() {
    const _newLocs = Object.values(newLocs);
    Object.getOwnPropertyNames(newLocs).forEach((n) => delete newLocs[n]);

    const len = _newLocs.length;
    if (len === 0) return;

    store.newLocationsArrived(_newLocs);
    setData(fillLocations(store.getLocations()));
  }


  return data.map((p) => <PointMarker key={p.id} loc={p} />);
}

export default observer(VehicleMap);

const PointMarker = observer(({ loc }) => {
  const markRef = useRef();
  const { coord } = loc;
  const text = `${loc.metadata.vehicleNo}<br />${t`时速`}${(coord.speed * 3.6).toFixed(1)}${t`公里`}`;

  useEffect(() => {
    markRef.current.instance.setRotation(coord.bearing);
  }, [coord]);

  return (
    <>
      <Marker ref={markRef} position={coord} icon={new BMapGL.Icon(carImg, new BMapGL.Size(38, 38))} />
      <Label position={coord} text={text} offset={new BMapGL.Size(16, -16)} />
    </>
  );
});
